package com.sunyur.tailor.channel.service.inner.protocol.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Lists;
import com.sunyur.tailor.channel.common.inner.base.SunyurListResult;
import com.sunyur.tailor.channel.common.inner.base.SunyurResult;
import com.sunyur.tailor.channel.common.inner.util.SunyurClientUtil;
import com.sunyur.tailor.channel.common.inner.util.SunyurResultUtil;
import com.sunyur.tailor.channel.common.middle.base.ChannelListResult;
import com.sunyur.tailor.channel.common.middle.base.ChannelResult;
import com.sunyur.tailor.channel.common.middle.enums.MiddleResultEnum;
import com.sunyur.tailor.channel.common.middle.util.ChannelListResultUtil;
import com.sunyur.tailor.channel.common.middle.util.ChannelResultUtil;
import com.sunyur.tailor.channel.service.inner.protocol.model.*;
import com.sunyur.tailor.channel.service.inner.protocol.param.*;
import com.sunyur.tailor.channel.service.inner.protocol.service.SunyurProtocolService;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * @ClassName SunyurProtocolServiceImpl
 * @Description 协议接口
 * @Author hao.tian
 * @Date 2021/5/11
 * @Version v1.0
 */
@Service("sunyurProtocolService")
public class SunyurProtocolServiceImpl implements SunyurProtocolService {

    private static final Logger LOGGER_INFO = LoggerFactory.getLogger(SunyurProtocolServiceImpl.class);
    private static final Logger LOGGER_ERROR = LoggerFactory.getLogger(SunyurProtocolServiceImpl.class);

    /**
     * 请求商越Client
     */
    @Autowired
    private SunyurClientUtil sunyurClient;

    /**
     * 协议信息创建接口 链接
     */
    @Value("${sunyur.api.createProtocol}")
    private String createProtocol;

    /**
     * 协议修改接口 链接
     */
    @Value("${sunyur.api.updateProtocol}")
    private String updateProtocol;

    /**
     * 获取协议信息行信息接口 链接
     */
    @Value("${sunyur.api.listProtocolItem}")
    private String listProtocolItem;

    /**
     * 获取协议信息头信息接口 链接
     */
    @Value("${sunyur.api.listProtocol}")
    private String listProtocol;

    /**
     * 获取协议运费信息接口 链接
     */
    @Value("${sunyur.api.getProtocolFreight}")
    private String getProtocolFreight;

    /**
     * 接受协议审批结果接口 链接
     */
    @Value("${sunyur.api.updateProtocolApproval}")
    private String updateProtocolApproval;

    /**
     * 批量获取协议头信息接口通过协议编码获取 链接
     */
    @Value("${sunyur.api.listProtocolByCode}")
    private String listProtocolByCode;

    /**
     * @Description 修改协议接口
     * @Param updateProtocolParam
     * @Return com.sunyur.tailor.channel.common.middle.base.ChannelResult<com.sunyur.tailor.channel.service.inner.protocol.model.UpdateProtocolModel>
     * @Author hao.tian
     * @Date 2021/5/11
     * @Version v1.0
     */
    @Override
    public ChannelResult<Boolean> createProtocol(CreateProtocolParam createProtocolParam) throws Exception {
        LOGGER_INFO.info("SunyurProtocolServiceImpl createProtocol param is {}", JSON.toJSONString(createProtocolParam));
        if (ObjectUtils.isEmpty(createProtocolParam)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), MiddleResultEnum.PARAM_NULL.getValue());
        }
        // 错误信息List
        List<String> errorMsgList = Lists.newArrayList();
        // 调用主线接口
        SunyurResult sunyurResult = sunyurClient.execPost(createProtocol, JSON.toJSONString(createProtocolParam), null);
        if (!SunyurResultUtil.isSuccess(sunyurResult)) {
            LOGGER_ERROR.error("createProtocol loop call sunyur request fail, param is {}, result is {}", JSON.toJSONString(createProtocolParam), JSON.toJSONString(sunyurResult));
            // 每批次错误信息收集
            errorMsgList.add(sunyurResult.getContent() + "-" + sunyurResult.getErrorMessage());
        }
        // 存在错误信息
        if (!CollectionUtils.isEmpty(errorMsgList)) {
            return ChannelResultUtil.error(MiddleResultEnum.FAILED.getCode(), JSON.toJSONString(errorMsgList));
        }
        return ChannelResultUtil.success(Boolean.TRUE);
    }

    /**
     * @Description 修改协议接口
     * @Param updateProtocolParam
     * @Return com.sunyur.tailor.channel.common.middle.base.ChannelResult<com.sunyur.tailor.channel.service.inner.protocol.model.UpdateProtocolModel>
     * @Author hao.tian
     * @Date 2021/5/11
     * @Version v1.0
     */
    @Override
    public ChannelResult updateProtocol(List<UpdateProtocolParam> updateProtocolParam) throws Exception {
        LOGGER_INFO.info("SunyurProtocolServiceImpl updateProtocol param is {}", JSON.toJSONString(updateProtocolParam));
        if (ObjectUtils.isEmpty(updateProtocolParam)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurProtocolServiceImpl updateProtocol param is null");
        }
        // 错误信息List
        List<String> errorMsgList = Lists.newArrayList();
        for (UpdateProtocolParam protocolParam : updateProtocolParam) {
            // 调用主线接口
            SunyurResult sunyurResult = sunyurClient.execPost(updateProtocol, JSON.toJSONString(protocolParam), null);
            if (!SunyurResultUtil.isSuccess(sunyurResult)) {
                LOGGER_ERROR.error("updateProtocol loop call sunyur request fail, param is {}, result is {}", JSON.toJSONString(protocolParam), JSON.toJSONString(sunyurResult));
                // 每批次错误信息收集
                errorMsgList.add(sunyurResult.getContent() + "-" + sunyurResult.getErrorMessage());
            }
        }
        // 存在错误信息
        if (!CollectionUtils.isEmpty(errorMsgList)) {
            return ChannelResultUtil.error(MiddleResultEnum.FAILED.getCode(), JSON.toJSONString(errorMsgList));
        }
        return ChannelResultUtil.success(null);
    }

    /**
     * @Description 获取协议行信息接口
     * @Param listProtocolItemParam
     * @Return com.sunyur.tailor.channel.common.middle.base.ChannelResult<com.sunyur.tailor.channel.service.inner.protocol.model.ListProtocolItemModel>
     * @Author hao.tian
     * @Date 2021/5/11
     * @Version v1.0
     */
    @Override
    public ChannelListResult<ListProtocolItemModel> listProtocolItem(ListProtocolItemParam listProtocolItemParam) throws Exception {
        LOGGER_INFO.info("SunyurProtocolServiceImpl listProtocolItem param is {}", JSON.toJSONString(listProtocolItemParam));
        if (ObjectUtils.isEmpty(listProtocolItemParam)) {
            return ChannelListResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurProtocolServiceImpl listProtocolItem param is null");
        }
        if (ObjectUtils.isEmpty(listProtocolItemParam.getPage())) {
            listProtocolItemParam.setPage(0);
        }
        if (ObjectUtils.isEmpty(listProtocolItemParam.getPageSize()) || listProtocolItemParam.getPageSize() > 100) {
            listProtocolItemParam.setPageSize(100);
        }
        // 调用主线接口
        TypeReference<SunyurListResult<ListProtocolItemModel>> typeReference = new TypeReference<SunyurListResult<ListProtocolItemModel>>() {
        };
        SunyurListResult<ListProtocolItemModel> sunyurListResult = sunyurClient.execListPost(listProtocolItem, JSON.toJSONString(listProtocolItemParam), typeReference);
        // 主线报错
        if (!SunyurResultUtil.isSuccess(sunyurListResult)) {
            return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), sunyurListResult.getErrorMessage());
        }
        // 判断是否存在下一页
        if (!SunyurResultUtil.isNextPage(sunyurListResult)) {
            return ChannelListResultUtil.success(sunyurListResult.getContent());
        }

        // 返回结果集
        List<ListProtocolItemModel> resultList = Lists.newArrayList();
        // 将第一次查询的结果收集
        resultList.addAll(sunyurListResult.getContent());
        // 循环查询剩余数据
        for (int i = listProtocolItemParam.getPage() + 1; i <= sunyurListResult.getTotalPage(); i++) {
            sunyurListResult.setPage(i);
            // 调用主线查询采购单头信息接口
            SunyurListResult<ListProtocolItemModel> sunyurPageResult = sunyurClient.execListPost(listProtocolItem, JSON.toJSONString(listProtocolItemParam), typeReference);
            // 某次调用主线返回错误（小概率，可能网络等原因，此时结果集数据不完整，本次查询失败）
            if (!SunyurResultUtil.isSuccess(sunyurPageResult)) {
                LOGGER_ERROR.error("listProtocolItem loop call sunyur request fail, param is {}, result is {}", JSON.toJSONString(listProtocolItemParam), JSON.toJSONString(sunyurPageResult));
                return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), sunyurPageResult.getErrorMessage());
            }
            resultList.addAll(sunyurPageResult.getContent());
        }
        return ChannelListResultUtil.success(resultList);
    }

    /**
     * @Description 获取协议头信息接口
     * @Param listProtocolParam
     * @Return com.sunyur.tailor.channel.common.middle.base.ChannelResult<com.sunyur.tailor.channel.service.inner.protocol.model.ListProtocolModel>
     * @Author hao.tian
     * @Date 2021/5/11
     * @Version v1.0
     */
    @Override
    public ChannelResult<List<ListProtocolModel>> listProtocol(List<ListProtocolParam> listProtocolParam) throws Exception {
        LOGGER_INFO.info("SunyurProtocolServiceImpl listProtocol param is {}", JSON.toJSONString(listProtocolParam));
        if (ObjectUtils.isEmpty(listProtocolParam)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurProtocolServiceImpl listProtocol param is null");
        }
        // 调用主线接口
        SunyurResult<List<ListProtocolModel>> sunyurResult = sunyurClient.execPost(listProtocol, JSON.toJSONString(listProtocolParam), new TypeReference<SunyurResult<List<ListProtocolModel>>>() {
        });
        // 主线报错
        if (!SunyurResultUtil.isSuccess(sunyurResult)) {
            return ChannelResultUtil.error(MiddleResultEnum.FAILED.getCode(), sunyurResult.getErrorMessage());
        }
        return ChannelResultUtil.success(sunyurResult.getContent());
    }

    /**
     * @Description 获取协议运费信息接口
     * @Param getProtocolFreightParam
     * @Return com.sunyur.tailor.channel.common.middle.base.ChannelResult<com.sunyur.tailor.channel.service.inner.protocol.model.GetProtocolFreightModel>
     * @Author hao.tian
     * @Date 2021/5/11
     * @Version v1.0
     */
    @Override
    public ChannelResult<GetProtocolFreightModel> getProtocolFreight(GetProtocolFreightParam getProtocolFreightParam) throws Exception {
        LOGGER_INFO.info("SunyurProtocolServiceImpl getProtocolFreight param is {}", JSON.toJSONString(getProtocolFreightParam));
        if (ObjectUtils.isEmpty(getProtocolFreightParam)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurProtocolServiceImpl getProtocolFreight param is null");
        }
        // 调用主线接口
        SunyurResult<GetProtocolFreightModel> sunyurResult = sunyurClient.execPost(getProtocolFreight, JSON.toJSONString(getProtocolFreightParam), new TypeReference<SunyurResult<GetProtocolFreightModel>>() {
        });
        // 主线报错
        if (!SunyurResultUtil.isSuccess(sunyurResult)) {
            return ChannelResultUtil.error(MiddleResultEnum.FAILED.getCode(), sunyurResult.getErrorMessage());
        }
        return ChannelResultUtil.success(sunyurResult.getContent());
    }

    /**
     * @Description 接收协议审批结果接口
     * @Param updateProtocolApprovalParam
     * @Return com.sunyur.tailor.channel.common.middle.base.ChannelResult
     * @Author hao.tian
     * @Date 2021/5/11
     * @Version v1.0
     */
    @Override
    public ChannelResult updateProtocolApproval(UpdateProtocolApprovalParam updateProtocolApprovalParam) throws Exception {
        LOGGER_INFO.info("SunyurProtocolServiceImpl updateProtocolApproval param is {}", JSON.toJSONString(updateProtocolApprovalParam));
        if (ObjectUtils.isEmpty(updateProtocolApprovalParam)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurProtocolServiceImpl updateProtocolApproval param is null");
        }
        // 调用主线接口
        SunyurResult sunyurResult = sunyurClient.execPost(updateProtocolApproval, JSON.toJSONString(updateProtocolApprovalParam), null);
        // 主线报错
        if (!SunyurResultUtil.isSuccess(sunyurResult)) {
            return ChannelResultUtil.error(MiddleResultEnum.FAILED.getCode(), sunyurResult.getErrorMessage());
        }
        return ChannelResultUtil.success(null);
    }

    /**
     * @Description 批量获取协议头信息接口通过协议编码获取
     * @Param listProtocolByCodeParam
     * @Return com.sunyur.tailor.channel.common.middle.base.ChannelResult<com.sunyur.tailor.channel.service.inner.protocol.model.ListProtocolByCodeModel>
     * @Author hao.tian
     * @Date 2021/5/11
     * @Version v1.0
     */
    @Override
    public ChannelResult<List<ListProtocolByCodeModel>> listProtocolByCode(ListProtocolByCodeParam listProtocolByCodeParam) throws Exception {
        LOGGER_INFO.info("SunyurProtocolServiceImpl listProtocolByCode param is {}", JSON.toJSONString(listProtocolByCodeParam));
        if (ObjectUtils.isEmpty(listProtocolByCodeParam)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurProtocolServiceImpl listProtocolByCode param is null");
        }
        //所有查询结果List
        List<ListProtocolByCodeModel> resultList = Lists.newArrayList();
        // 参数按长度分割
        List<List<String>> protocolCodes = Lists.partition(listProtocolByCodeParam.getProtocolCodes(), 20);
        // 错误信息List
        List<String> errorMsgList = Lists.newArrayList();
        ListProtocolByCodeParam listProtocolByCodeParamClient = new ListProtocolByCodeParam();
        TypeReference<SunyurResult<List<ListProtocolByCodeModel>>> typeReference = new TypeReference<SunyurResult<List<ListProtocolByCodeModel>>>() {};
        for (List<String> protocolCode : protocolCodes) {
            listProtocolByCodeParamClient.setProtocolCodes(protocolCode);
            // 调用主线接口
            SunyurResult<List<ListProtocolByCodeModel>> sunyurResult = sunyurClient.execPost(listProtocolByCode, JSON.toJSONString(listProtocolByCodeParamClient), typeReference);
            if (SunyurResultUtil.isSuccess(sunyurResult)) {
                resultList.addAll(sunyurResult.getContent());
            } else {
                LOGGER_ERROR.error("listProtocolByCode loop call sunyur request fail, param is {}, result is {}", JSON.toJSONString(listProtocolByCodeParamClient), JSON.toJSONString(sunyurResult));
                // 每批次错误信息收集
                errorMsgList.add(sunyurResult.getContent() + "-" + sunyurResult.getErrorMessage());
            }
        }
        // 存在错误信息
        if (!CollectionUtils.isEmpty(errorMsgList)) {
           return ChannelResultUtil.error(MiddleResultEnum.FAILED.getCode(), JSON.toJSONString(errorMsgList));
        }
        return ChannelResultUtil.success(resultList);
    }

}
